package com.starlink.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.hutool.core.convert.Convert;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.PageHelper;
import com.lop.open.api.sdk.domain.ECAP.CommonQueryOrderApi.commonGetOrderTraceV1.CommonOrderTraceDetail;
import com.lop.open.api.sdk.domain.ECAP.CommonQueryOrderApi.commonGetOrderTraceV1.CommonOrderTraceResponse;
import com.starlink.client.jd.JdClient;
import com.starlink.client.jd.properties.JdProperties;
import com.starlink.client.jd.request.TraceQueryRequest;
import com.starlink.common.domain.BaseEntity;
import com.starlink.model.domain.*;
import com.starlink.model.vo.AddressVO;
import com.starlink.service.*;
import org.springframework.data.domain.Pageable;
import com.starlink.common.utils.AssertUtil;
import com.starlink.model.dtomapper.SchoolbagOrderReadRecordDtoMapper;
import com.starlink.mapper.SchoolbagOrderReadRecordMapper;
import com.starlink.model.request.SchoolbagOrderReadRecordRequest;
import com.starlink.model.util.SchoolbagOrderReadRecordConvert;
import com.starlink.model.vo.SchoolbagOrderReadRecordVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import static com.starlink.utils.PageUtils.getOrderBy;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @author zhanghong
 */
@Service
public class SchoolbagOrderReadRecordServiceImpl extends ServiceImpl<SchoolbagOrderReadRecordMapper, SchoolbagOrderReadRecordDO> implements SchoolbagOrderReadRecordService {
    @Autowired
    private SchoolbagOrderReadRecordMapper schoolbagOrderReadRecordMapper;
    @Autowired
    private SchoolbagOrderService schoolbagOrderService;
    @Autowired
    private SchoolbagService schoolbagService;
    @Autowired
    private SchoolbagGroupService schoolbagGroupService;
    @Autowired
    private MallBooksService mallBooksService;
    @Autowired
    private AddressService addressService;
    @Autowired
    private JdProperties jdProperties;
    @Autowired
    private JdClient jdClient;

    @Override
    public SchoolbagOrderReadRecordVO getByKey(long id) {
        SchoolbagOrderReadRecordVO schoolbagOrderReadRecordVO = SchoolbagOrderReadRecordDtoMapper.INSTANCE.do2VO(getById(id));

        List<MallBooksDO> bookList = mallBooksService.queryByGroupBagId(schoolbagOrderReadRecordVO.getSchoolbagGroupBagId());
        schoolbagOrderReadRecordVO.setBookList(bookList);
        // 收件地址信息
        AddressVO itemAddressVo = addressService.getByKey(schoolbagOrderReadRecordVO.getAddressId());
        schoolbagOrderReadRecordVO.setAddressId(itemAddressVo.getId());
        schoolbagOrderReadRecordVO.setReceiver(Optional.ofNullable(itemAddressVo).map(AddressVO::getReceiver).orElse(null));
        schoolbagOrderReadRecordVO.setProvince(Optional.ofNullable(itemAddressVo).map(AddressVO::getProvince).orElse(null));
        schoolbagOrderReadRecordVO.setCity(Optional.ofNullable(itemAddressVo).map(AddressVO::getCity).orElse(null));
        schoolbagOrderReadRecordVO.setArea(Optional.ofNullable(itemAddressVo).map(AddressVO::getArea).orElse(null));
        schoolbagOrderReadRecordVO.setDetail(Optional.ofNullable(itemAddressVo).map(AddressVO::getDetail).orElse(null));
        schoolbagOrderReadRecordVO.setDetail(Optional.ofNullable(itemAddressVo).map(AddressVO::getMobile).orElse(null));


        // 收件地址信息
        return schoolbagOrderReadRecordVO;
    }

    @Override
    public PageInfo<SchoolbagOrderReadRecordVO> pageQuery(Pageable pageable,SchoolbagOrderReadRecordRequest request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize(), getOrderBy(pageable.getSort())).setReasonable(true);
        List<SchoolbagOrderReadRecordDO> list = schoolbagOrderReadRecordMapper.listQuery(request);
        List<SchoolbagOrderReadRecordVO> schoolbagOrderReadRecordVOList = SchoolbagOrderReadRecordConvert.buildSchoolbagOrderReadRecordVoList(list);
        return new PageInfo(schoolbagOrderReadRecordVOList);
    }

    @Override
    public List<SchoolbagOrderReadRecordVO> listQuery(SchoolbagOrderReadRecordRequest request) {
        List<SchoolbagOrderReadRecordDO> list = schoolbagOrderReadRecordMapper.selectDOList(SchoolbagOrderReadRecordDtoMapper.INSTANCE.request2DO(request));
        List<SchoolbagOrderReadRecordVO> schoolbagOrderReadRecordVOS = SchoolbagOrderReadRecordConvert.buildSchoolbagOrderReadRecordVoList(list);
        return schoolbagOrderReadRecordVOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(SchoolbagOrderReadRecordRequest request) {
        save(SchoolbagOrderReadRecordDtoMapper.INSTANCE.request2DO(request));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByKey(SchoolbagOrderReadRecordRequest request) {
        AssertUtil.assertNotNull(request.getId(), "id不能为空");
        SchoolbagOrderReadRecordDO one = lambdaQuery().eq(BaseEntity::getId, request.getId()).one();
        AssertUtil.assertNotNull(one, "数据不存在");
        saveOrUpdate(SchoolbagOrderReadRecordDtoMapper.INSTANCE.request2DO(request));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteDOByIds(String ids) {
        schoolbagOrderReadRecordMapper.deleteDOByIds(Convert.toStrArray(ids));
        return true;
    }

    @Async
    @Override
    public boolean createOrderReadRecord(Long schoolbagOrderId) {
        // 查询订单
        SchoolbagOrderDO schoolbagOrderDO = schoolbagOrderService.lambdaQuery().eq(SchoolbagOrderDO::getId, schoolbagOrderId).last("limit 1").one();
        // 查询订单书包
        SchoolbagDO schoolbagDO = schoolbagService.lambdaQuery().eq(BaseEntity::getId, schoolbagOrderDO.getId()).last("limit 1").one();
        // 查询分组中书包中出借数量最多，但是不是12个书包都处于出借状态的书包, 找出分组
        SchoolbagGroupDO one = schoolbagGroupService.lambdaQuery().lt(SchoolbagGroupDO::getBorrowNum, 12).orderByDesc(SchoolbagGroupDO::getBorrowNum).last("limit 1").one();
        // 当前用户要加入的就是该分组

        /**
         * 确定当前日期
         * case 1： date < 15号；当月15号就会给他发书包； 当前用户第一期书包=正在运转的当月书包中的最后一位进入该分组的用户所阅读书包的分组下标为N，则为N+1
         * case 1： date >= 15号；次月15号就会给他发书包；当前用户第一期书包=正在运转的当月书包中的最后一位进入该分组的用户所阅读书包的分组下标为N，则为N+2
         *
         * 确定了当前用户第一期阅读书包是，分组中的那个书包下标，那么就可以推算出该该用户未来12期所读的所有书包，也就可以生成记录了
         *
         *
         * 定时任务实现思路：
         * 15号发送书包
         *  1.什么时候生成物流单？15号快递小哥揽收发走，那么就是15号下单，总仓打印快递单并准备书包进行物流包装后贴上快递单
         *  2.找出对应的单子并下物流单（按照现有设计，发货是需要商家手动点击打印进行物流单的下发给京东）--这里就是需要人工进行所有物流单的打印，应该是所有要打印的任务先生成，然后可以一键打印
         *
         * 12号回收书包
         *  1.12号下单，12号上午快递小哥上们揽收
         *  2.找出对应的单子并下物流单
         *
         */

        return true;
    }

    @Override
    public List<CommonOrderTraceDetail> traceQuery(SchoolbagOrderReadRecordRequest request) {
        SchoolbagOrderReadRecordVO schoolbagOrderReadRecordVO = getByKey(request.getId());
        AssertUtil.assertNotNull(schoolbagOrderReadRecordVO, "阅读记录不存在");
        // 订单追综
        TraceQueryRequest traceQueryRequest = new TraceQueryRequest();
        traceQueryRequest.setWaybillCode(schoolbagOrderReadRecordVO.getExpressDeliveryWaybillCode());
//        traceQueryRequest.setOrderCode(logisticsDO.getLogisticsOrderId());
        traceQueryRequest.setOrderOrigin(1);
        traceQueryRequest.setCustomerCode(jdProperties.getCustomerCode());
        CommonOrderTraceResponse commonOrderTraceResponse = jdClient.traceQuery(traceQueryRequest);
        return commonOrderTraceResponse.getTraceDetails();
    }

    @Override
    public Boolean confirm(SchoolbagOrderReadRecordRequest request) {
        SchoolbagOrderReadRecordDO schoolbagOrderReadRecordDO = schoolbagOrderReadRecordMapper.selectDOById(request.getId());
        AssertUtil.assertNotNull(schoolbagOrderReadRecordDO, "阅读记录不存在");
        schoolbagOrderReadRecordDO.setServiceStatus(2);
        schoolbagOrderReadRecordDO.setUserConfirmTime(new Date());
        return saveOrUpdate(schoolbagOrderReadRecordDO);
    }

    @Override
    public Boolean withholdingDeposit(SchoolbagOrderReadRecordRequest request) {
        SchoolbagOrderReadRecordDO schoolbagOrderReadRecordDO = schoolbagOrderReadRecordMapper.selectDOById(request.getId());
        AssertUtil.assertNotNull(schoolbagOrderReadRecordDO, "阅读记录不存在");
        AssertUtil.assertNotNull(request.getDeductionMoney(), "扣除金额不能为空");
        schoolbagOrderReadRecordDO.setIsDeductionDeposit(1);
        schoolbagOrderReadRecordDO.setDeductionImg(request.getDeductionImg());
        schoolbagOrderReadRecordDO.setDeductionReason(request.getDeductionReason());
        schoolbagOrderReadRecordDO.setDeductionMoney(request.getDeductionMoney());
        saveOrUpdate(schoolbagOrderReadRecordDO);

        // todo 增加押金扣除记录
        return true;
    }

    @Override
    public Boolean appeal(SchoolbagOrderReadRecordRequest request) {
        SchoolbagOrderReadRecordDO schoolbagOrderReadRecordDO = schoolbagOrderReadRecordMapper.selectDOById(request.getId());
        AssertUtil.assertNotNull(schoolbagOrderReadRecordDO, "阅读记录不存在");
        AssertUtil.assertNotNull(request.getAppealDesc(), "申诉说明不能为空");
        AssertUtil.assertNotNull(request.getAppealPicture(), "申诉图片不能为空");

        schoolbagOrderReadRecordDO.setAppealDesc(request.getAppealDesc());
        schoolbagOrderReadRecordDO.setAppealPicture(request.getAppealPicture());
        saveOrUpdate(schoolbagOrderReadRecordDO);
        return true;
    }
}
